package disco;

import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import tiempo.Temporizador;

public class CFQDispatch implements Runnable {

   Map cfqPrioritySin;
   CFQQueue[] queueAsinc;

   public CFQDispatch(CFQQueue[] queueAsinc, Map cfqPrioritySin) {

       this.cfqPrioritySin = cfqPrioritySin;
       this.queueAsinc = queueAsinc;
       new Thread(this, "cfqDispatch").start();
   }

   /*
    * Mètodo en donde se implementa el algoritmo del scheduler para despachar
    * las peticiones al dispatchQueue
    */
   public void run() {
       while(true) {
            //Ciclo para revisar colas de peticiones asíncronas
            final String toAppendAsinc;
            final String toAppendSinc;
            String auxAsinc = "";
            String auxSinc = "";
            //Ciclo para revisar colas de peticiones asíncronas
            for(int i = 0; i < CFQ.numPrioridades; i++) {
                long msIni = System.currentTimeMillis();
                long msActual = msIni;
                CFQQueue colaActual = queueAsinc[i];
                while(msActual < queueAsinc[i].slice + msIni) {
                    //Despachar de colaActual e ir incrementando la variable
                    //milisegundos
                    if (colaActual.isEmpty()) {
                       break;
                    }
                    CFQRequest actual = colaActual.get();
                    if (actual == null) {
                        break;
                    }
                    Main.dispatchQueue.put(actual);
                    msActual = System.currentTimeMillis();
                    auxAsinc += actual.toString();
                }
//                auxAsinc += "___Fin time slice cola asincrona " + i + "___\n";
            }
            toAppendAsinc = auxAsinc;

           //TODO ciclar para colas de cada proceso (las sìncronas) y despachar
           //de las mismas
           for(int i = 0; i < CFQ.numPrioridades; i++) {
               long msIni = System.currentTimeMillis();
               long msActual = msIni;
               Map priority = (Map) cfqPrioritySin.get(i);
               Iterator itr = priority.values().iterator();
               while(itr.hasNext()){
                    CFQQueue colaActual = (CFQQueue) itr.next();
                    if (colaActual.isEmpty()) {
                        break;
                    }
                    while(msActual < colaActual.slice + msIni) {
                        //Despachar de colaActual e ir incrementando la variable
                        //milisegundos

                        CFQRequest actual = colaActual.get();
                        if (actual == null) {
                            break;
                        }
                        Main.dispatchQueue.put(actual);
                        msActual = System.currentTimeMillis();
                        auxSinc += actual.toString();

                    }
//                    auxSinc += "___Fin time slice cola sincrona " + i + "___\n";
                }
            }
            toAppendSinc = auxSinc;
            final String concat = toAppendAsinc + toAppendSinc;
            if(!concat.equals("")){
                //Interfaz
                try{
                SwingUtilities.invokeAndWait(new Runnable() {
                    public void run() {
                        Main.actualizarDispatchQueueGui(concat);
                    }
                });
                } catch (InterruptedException ex) {
//                    Logger.getLogger(CFQDispatch.class.getName()).log(Level.SEVERE, null, ex);
                } catch (InvocationTargetException e) {
//                    Logger.getLogger(CFQDispatch.class.getName()).log(Level.SEVERE, null, e);
                }
            Temporizador.sleep();
        }
       }
    }
}